/*
 *  Matrix4.h
 *  zray-gui
 *
 *  Created by czalkin on 1/10/09.
 *  Copyright 2009 __MyCompanyName__. All rights reserved.
 *
 */

#ifndef MATRIX_4_H_
#define MATRIX_4_H_

class Vector3;
class Vector4;
class Point3;

class Matrix4
{
	friend class Vector4;
	friend class Vector3;
	friend class Point3;
	
public:
	Matrix4();
	Matrix4( const Matrix4 &rhs );
	Matrix4( const Vector3 &x, const Vector3 &y, const Vector3 &z );
	Matrix4( const Vector3 &x, const Vector3 &y, const Vector3 &z, const Vector3 &t );
	Matrix4( float* col1, float *col2, float *col3, float* col4 );
	Matrix4( float* all );
	Matrix4( float x0, float x1, float x2, float x3,
			 float y0, float y1, float y2, float y3,
			 float z0, float z1, float z2, float z3,
			 float t0, float t1, float t2, float t3 );
	
	Matrix4 getRotation() const;
	const Vector3 getTranslation() const;
	
	static Matrix4 createScale( const float x, const float y, const float z )
	{
		return Matrix4( x, 0, 0, 0,    0, y, 0, 0,   0, 0, z, 0,  0, 0, 0, 1.0f );
	}
	
	static Matrix4 createTranslate( const float x, const float y, const float z )
	{
		return Matrix4( 1.0f, 0, 0, 0,   0, 1.0f, 0, 0,    0, 0, 1.0f, 0,  x, y, z, 1.0f );
	}
	
	static Matrix4 createRotationX( const float deg );	
	static Matrix4 createRotationY( const float deg );
	static Matrix4 createRotationZ( const float deg );
	
	operator float*() { return v; }
	float* getFloatArray() { return v; }
	
	Matrix4 operator*( const Matrix4 &rhs ) const;
	Matrix4& operator *=( const Matrix4 &rhs );
	Vector4 operator*( const Vector4 &vec ) const;
	Vector3 operator*( const Vector3 &vec ) const;
	
	Vector3 mult33( const Vector3 &vecIn ) const;
	Vector3 mult34( const Vector3 &vecIn ) const;
	Point3 mult34( const Point3 &vecIn ) const;
	
	Matrix4 invert();
	float determinant();
	
	
	float at(int col, int row);
	void set(int col, int row, float val );

	static Matrix4 lookat_matrix( Vector3 eye, Vector3 at, Vector3 up, bool doTranslation);
	static Matrix4 viewport_matrix( const float width, const float height);

	Matrix4 scale( float scale );
	
	
protected:
	float v[16];

};

#endif
